﻿using System;
using Microsoft.AspNetCore.Mvc;
using System.IO;
using System.Numerics;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using System.Drawing;
using System.Drawing.Imaging;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Hosting;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.ModelBinding;
using MySql.Data;

namespace SharpSoft.Web
{
    /// <summary>
    /// 提供人机验证码接口
    /// </summary>
    [AllowAnonymous]
    public class AuthCodeController : BaseController
    { 
        private AppConfig config;
         
        public AuthCodeController(IOptions<AppConfig> appconfig, IHttpContextAccessor p_accessor, IWebHostEnvironment p_env, DatabaseService p_databaseService) : base(appconfig, p_accessor, p_env, p_databaseService)
        {
            this.config = appconfig.Value;
        }

        byte[] CreateImg(string num)
        {
            //创建一个位图对象,并设置该位图的长宽
            Bitmap myBmp = new Bitmap(150, 50);
            //用myBmp创建一个GDI+对象
            Graphics myGp = Graphics.FromImage(myBmp);
            //创建一个产生随机数的对象
            Random r = new Random();
            string pass = num;
            //声明一个字符串数组,用来存储字体类型
            string[] font = { "微软雅黑", "仿宋", "幼圆", "宋体", "隶书" };
            //声明一个Color数组,用来储存字体颜色
            Color[] colors = { Color.Red, Color.Yellow, Color.White, Color.WhiteSmoke, Color.Pink };
            //绘制验证码
            //验证码字体类型、颜色,字体的坐标都是随机的
            //能声明在循环外面的变量尽量声明在循环外面
            Point point = new Point();
            for (int i = 0; i < num.Length; i++)
            {
                point.X = 30 * i;
                point.Y = r.Next(0, 15);
                //调用GDI+的DrawString方法来绘制字符串
                myGp.DrawString(pass[i].ToString(), new Font(font[r.Next(0, font.Length)], 20, FontStyle.Italic), new SolidBrush(colors[r.Next(0, colors.Length)]), point);
            }
            //绘制线条
            //声明两个直线的端点
            Point pointA = new Point();
            Point pointB = new Point();
            for (int i = 0; i < 15; i++)
            {
                //随机给点赋坐标
                pointA.X = r.Next(0, myBmp.Width);
                pointA.Y = r.Next(0, myBmp.Height);
                pointB.X = r.Next(0, myBmp.Width);
                pointB.Y = r.Next(0, myBmp.Height);
                //绘制线条
                myGp.DrawLine(new Pen(colors[r.Next(0, colors.Length)]), pointA, pointB);
            }
            //绘制噪点
            Point pointC = new Point();
            for (int i = 0; i < 300; i++)
            {
                pointC.X = r.Next(0, myBmp.Width);
                pointC.Y = r.Next(0, myBmp.Height);
                //噪点直接用位图对象直接绘制
                myBmp.SetPixel(pointC.X, pointC.Y, colors[r.Next(0, colors.Length)]);
            }

            var ms = new MemoryStream();
            //位图保存在内存流
            myBmp.Save(ms, ImageFormat.Jpeg);

            return ms.ToArray();
        }


        private byte[] GetAuthCodeBytes()
        {
            if (HttpContext.Session == null || !HttpContext.Session.IsAvailable)
            {//检查是否启用了Session
                throw new Exception(Properties.Resources.error_authcode_without_session);
            }
            string valcode = AuthCode.Generate((AuthCodeType)config.AuthCodeType, config.AuthCodeCount);
            HttpContext.Session.SetString(ValCode_SessionValueKey, valcode);
            return CreateImg(valcode);
        }

        [AllowAnonymous]
        [HttpGet]
        public FileContentResult Get()
        {
            var buf = this.GetAuthCodeBytes();
            return File(buf, "image/png", "code.png");
        }
        [AllowAnonymous]
        [HttpGet]
        public ApiResult GetBase64()
        {
            var buf = this.GetAuthCodeBytes();
            var base64 = Convert.ToBase64String(buf);
            return Success(base64);
        }
    }
}
